package com.waikuai.shop.controller;

import com.waikuai.shop.common.result.Result;
import com.waikuai.shop.dto.LoginRequest;
import com.waikuai.shop.dto.LoginResponse;
import com.waikuai.shop.service.AuthService;
import com.waikuai.shop.service.CaptchaService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * 认证控制器
 * @author waikuai
 */
@Slf4j
@RestController
@RequestMapping("/auth")
@RequiredArgsConstructor
public class AuthController {

    private final AuthService authService;
    private final CaptchaService captchaService;

    /**
     * 用户登录
     */
    @PostMapping("/login")
    public Result<LoginResponse> login(@Validated @RequestBody LoginRequest loginRequest) {
        log.info("用户登录请求: account={}, type={}", loginRequest.getAccount(), loginRequest.getLoginType());

        try {
            LoginResponse response = authService.login(loginRequest);
            return Result.success("登录成功", response);
        } catch (Exception e) {
            log.error("用户登录失败: {}", e.getMessage());
            throw e;
        }
    }

    /**
     * 用户登出
     */
    @PostMapping("/logout")
    public Result<String> logout(@RequestHeader("Authorization") String token) {
        log.info("用户登出请求");

        try {
            if (token != null && token.startsWith("Bearer ")) {
                token = token.substring(7);
            }
            authService.logout(token);
            return Result.success("登出成功");
        } catch (Exception e) {
            log.error("用户登出失败: {}", e.getMessage());
            return Result.error("登出失败");
        }
    }

    /**
     * 刷新令牌
     */
    @PostMapping("/refresh")
    public Result<Map<String, String>> refreshToken(@RequestHeader("Authorization") String token) {
        log.info("刷新令牌请求");

        try {
            if (token != null && token.startsWith("Bearer ")) {
                token = token.substring(7);
            }

            String newToken = authService.refreshToken(token);
            Map<String, String> response = new HashMap<>();
            response.put("token", newToken);
            response.put("tokenType", "Bearer");

            return Result.success("令牌刷新成功", response);
        } catch (Exception e) {
            log.error("刷新令牌失败: {}", e.getMessage());
            return Result.error("令牌刷新失败");
        }
    }

    /**
     * 生成验证码
     */
    @GetMapping("/captcha")
    public void generateCaptcha(HttpServletResponse response) throws IOException {
        response.setContentType("image/png");
        response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
        response.setHeader("Pragma", "no-cache");

        String key = UUID.randomUUID().toString();
        BufferedImage image = captchaService.generateCaptcha(key);

        // 将验证码key返回给前端
        response.setHeader("Captcha-Key", key);

        // 使用PNG格式，避免JPEG不支持某些颜色模型的问题
        ImageIO.write(image, "PNG", response.getOutputStream());
        log.debug("生成验证码: key={}", key);
    }

    /**
     * 生成验证码（返回JSON格式，包含Key）
     */
    @GetMapping("/captcha-info")
    public Result<Map<String, Object>> generateCaptchaInfo() throws IOException {
        String key = UUID.randomUUID().toString();
        BufferedImage image = captchaService.generateCaptcha(key);

        // 将图像转换为Base64
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ImageIO.write(image, "PNG", baos);
        byte[] imageBytes = baos.toByteArray();
        String base64Image = Base64.getEncoder().encodeToString(imageBytes);

        Map<String, Object> result = new HashMap<>();
        result.put("captchaKey", key);
        result.put("captchaImage", "data:image/png;base64," + base64Image);

        return Result.success("验证码生成成功", result);
    }

    /**
     * 获取当前用户信息
     */
    @GetMapping("/user")
    public Result<Map<String, Object>> getCurrentUser() {
        try {
            // 从Security上下文获取当前用户
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            if (authentication == null || authentication.getPrincipal() == null) {
                return Result.error("用户未登录");
            }

            UserDetails userDetails = (UserDetails) authentication.getPrincipal();
            String username = userDetails.getUsername();

            // 获取完整用户信息
            com.waikuai.shop.dto.UserInfo userInfo = authService.getUserInfoByUsername(username);

            // 构建返回数据
            Map<String, Object> result = new HashMap<>();
            result.put("id", userInfo.getId());
            result.put("username", userInfo.getUsername());
            result.put("realName", userInfo.getRealName());
            result.put("phone", userInfo.getPhone());
            result.put("email", userInfo.getEmail());
            result.put("avatar", userInfo.getAvatar());
            result.put("gender", userInfo.getGender());
            result.put("birthday", userInfo.getBirthday());
            result.put("accountBalance", userInfo.getAccountBalance());
            result.put("lastLoginTime", userInfo.getLastLoginTime());
            
            // 转换角色列表
            if (userInfo.getRoles() != null && !userInfo.getRoles().isEmpty()) {
                result.put("roles", userInfo.getRoles().stream()
                    .map(role -> {
                        Map<String, Object> roleMap = new HashMap<>();
                        roleMap.put("id", role.getId());
                        roleMap.put("roleName", role.getRoleName());
                        roleMap.put("roleCode", role.getRoleCode());
                        roleMap.put("description", role.getDescription());
                        return roleMap;
                    })
                    .collect(java.util.stream.Collectors.toList()));
            } else {
                result.put("roles", new ArrayList<>());
            }

            log.info("获取当前用户信息成功: username={}", username);
            return Result.success(result);
        } catch (Exception e) {
            log.error("获取当前用户信息失败: {}", e.getMessage(), e);
            return Result.error("获取用户信息失败");
        }
    }
}